package it.bit.jlightqueryer.bl;

import java.applet.Applet;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.JTable;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

/**
 * "U" stands for Utilities :)
 */
public class U {

	/**
	 * Return stacktrace of an exception to a string.<br>
	 * Taked in the web somewhere...
	 * @param e
	 * @return stacktrace of an exception to a string.
	 */
	static public String stack2string(Throwable e) {
		try {
			java.io.StringWriter sw = new java.io.StringWriter();
			java.io.PrintWriter pw = new java.io.PrintWriter(sw);
			e.printStackTrace(pw);
			return sw.toString();
		}
		catch (Exception e2) {
			return "bad stack2string";
		}
	}

	/**
	 * Sets the location of the dialog relative to the specified
	 * component. If the component is not currently showing, the
	 * dialog is centered on the screen.
	 *
	 * @param c  the component in relation to which the dialog's location
	 *           is determined
	 */
	public static void setLocationRelativeTo(Window d, Component c) {
		Container root=null;

		if (c != null) {
			if (c instanceof Window || c instanceof Applet) {
			   root = (Container)c;
			} else {
				Container parent;
				for(parent = c.getParent() ; parent != null ; parent = parent.getParent()) {
					if (parent instanceof Window || parent instanceof Applet) {
						root = parent;
						break;
					}
				}
			}
		}

		if((c != null && !c.isShowing()) || root == null ||
		   !root.isShowing()) {
			Dimension         paneSize = d.getSize();
			Dimension         screenSize = d.getToolkit().getScreenSize();

			d.setLocation((screenSize.width - paneSize.width) / 2,
						(screenSize.height - paneSize.height) / 2);
		} else {
			Dimension invokerSize = c.getSize();
			Point invokerScreenLocation;

			// If this method is called directly after a call to
			// setLocation() on the "root", getLocationOnScreen()
			// may return stale results (Bug#4181562), so we walk
			// up the tree to calculate the position instead
			// (unless "root" is an applet, where we cannot walk
			// all the way up to a toplevel window)
			//
			if (root instanceof Applet) {
				invokerScreenLocation = c.getLocationOnScreen();
			} else {
				invokerScreenLocation = new Point(0,0);
				Component tc = c;
				while (tc != null) {
					Point tcl = tc.getLocation();
					invokerScreenLocation.x += tcl.x;
					invokerScreenLocation.y += tcl.y;
					if (tc == root) {
						break;
					}
					tc = tc.getParent();
				}
			}


			Rectangle           dialogBounds = d.getBounds();
			int                 dx = invokerScreenLocation.x+((invokerSize.width-dialogBounds.width)>>1);
			int                 dy = invokerScreenLocation.y+((invokerSize.height - dialogBounds.height)>>1);
			Dimension           ss = d.getToolkit().getScreenSize();

			if (dy+dialogBounds.height>ss.height) {
				dy = ss.height-dialogBounds.height;
				dx = invokerScreenLocation.x<(ss.width>>1) ? invokerScreenLocation.x+invokerSize.width :
					invokerScreenLocation.x-dialogBounds.width;
			}
			if (dx+dialogBounds.width>ss.width) dx = ss.width-dialogBounds.width;
			if (dx<0) dx = 0;
			if (dy<0) dy = 0;
			d.setLocation(dx, dy);
		}
	}

	/**
	 * Set nice widths of columns of a JTable
	 * Taked from experience...
	 * @param jTable
	 */
	public static void adjustColumns(JTable jTable)
	{
		TableModel model = jTable.getModel();
		int nCols = model.getColumnCount();
		int nRows = model.getRowCount();
		int[] maxWidths = new int[nCols];
		java.awt.FontMetrics m = jTable.getFontMetrics(jTable.getFont());
		for (int col = 0; col < nCols; col++)
			maxWidths[col] = m.stringWidth(model.getColumnName(col));
		for (int row = 0; row < nRows; row++)
		{
			for (int col = 0; col < nCols; col++)
			{
				Object cell = model.getValueAt(row, col);
				String cellStr = "";
				cellStr = "00/00/0000";
				if (cell != null && !(cell instanceof Date)) {
						cellStr = cell.toString();
				}

				int width = m.stringWidth(cellStr);
				if (width > maxWidths[col])
					maxWidths[col] = width;
			}
		}
		jTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		for (int col = 0; col < nCols; col++)
		{
			maxWidths[col] += 5;
			TableColumn c = jTable.getColumnModel().getColumn(col);
			//c.setMinWidth(maxWidths[col]);
			c.setMinWidth(3);
			c.setWidth(maxWidths[col]);
			c.setPreferredWidth(maxWidths[col]);
			jTable.sizeColumnsToFit(col);
		}
	}

	/**
	 * Having a string with some variables that begin and end with particular strings,<br>
	 * the method return an array of String that idendify all variables
	 * @param string to analyze
	 * @param begin variable string
	 * @param end variable string
	 * @return
	 */
	public static String[] getVariables(String s, String b, String e) {
		if (s == null || s.trim().length()<1) return new String[0];
		List vars = new ArrayList();
		String wrkS = new String(s);
		int idx = -1;
		do {
			idx = wrkS.indexOf(b);
			if (idx>-1) {
				wrkS = wrkS.substring(idx+b.length());
				idx = wrkS.indexOf(e);
				vars.add(wrkS.substring(0,idx));
			}
		} while (idx>-1);
		String[] result = new String[vars.size()];
		for (int i = 0; i < result.length; i++) {
			result[i] = (String) vars.get(i);
		}
		return result;
	}

	/**
	 * Like getVariables but return a string with values at places of variables
	 * @see getVariables
	 * @param original string
	 * @param variables
	 * @param values
	 * @param begin variable string
	 * @param end variable string
	 * @return
	 */
	public static String setVariables(String s, String[] var, String[] val, String b, String e) {
		if (s == null || s.trim().length()<1) return s;
		if (var == null || var.length<1) return s;
		if (val == null || val.length<1) return s;
		if (var.length != val.length) return s;
		String wrkS = new String(s);
		for (int i = 0; i < var.length; i++) {
			wrkS = replace(wrkS, b+var[i]+e, val[i]);
		}
		return wrkS;
	}

	/**
	 * Replace a string with a string in a string...
	 * @param original string
	 * @param string to be replaced
	 * @param string for replace
	 * @return
	 */
	public static String replace(String str, String from, String to)
	{
		if (from.length() == 0)
			return str;
		if (str.indexOf(from)<0)
			return str;

		int startPos = 0;
		int i = 0;
		int gap = 0;
		int fromLen = from.length();
		int toLen = to.length();
		StringBuffer buf = new StringBuffer(str);
		while ((i = str.indexOf(from, startPos)) >= 0)
		{
			buf.replace(i + gap, i + gap + fromLen, to);
			startPos = i + fromLen;
			gap += toLen - fromLen;
		}
		return buf.toString();
	}

}
